记录:读取Word将内容原样渲染到html 您所在的位置:网站首页 vue 富文本转html 记录:读取Word将内容原样渲染到html

记录:读取Word将内容原样渲染到html

2023-06-28 18:06| 来源: 网络整理| 查看: 265

一个需求:要求用户选择一个Word,能够自动读取Word里的内容,将内容以及格式原封不动的渲染到富文本编辑器里,作为草稿,用以发布。

t01f0a0554d8ee5643a.jpg 附赠壁纸一张

小弟菜鸡儿,挠头半天不得,幸得一老哥支持,分享一套代码,开始分析:

引入得包 package com.itmake.tools.word; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.converter.WordToHtmlConverter; import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter; import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions; import org.apache.poi.xwpf.usermodel.XWPFDocument; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.util.Base64; import java.util.HashMap; import java.util.Map; 复制代码 引入得依赖 fr.opensagres.xdocreport fr.opensagres.xdocreport.document 1.0.5 fr.opensagres.xdocreport org.apache.poi.xwpf.converter.xhtml 1.0.5 org.apache.poi poi 3.12 org.apache.poi poi-scratchpad 3.12 复制代码 逻辑代码(转换".docx"格式Word) /** * docx(2007版本word) 转换成 html * * @param docxIs docx 文件输入流 * @return 转换成的 html 代码 * @throws IOException 异常 */ public String docxToHtml(InputStream docxIs) throws IOException { Map image = new HashMap(); // 转换参数设置 XHTMLOptions options = XHTMLOptions.create(); // 保存图片数据,并进行 base64 编码 options.setExtractor((s, bytes) -> image.put(s, BASE64_IMAGE_PREFIX + Base64.getEncoder().encodeToString(bytes))); // 设置图片路径,这里替换为 base64 字符 options.URIResolver(image::get); options.setIgnoreStylesIfUnused(false); options.setFragment(true); // 加载 word 文档生成 XWPFDocument对象 XWPFDocument document = new XWPFDocument(docxIs); // 用于读取转换后的数据 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 转换 word XHTMLConverter.getInstance().convert(document, byteArrayOutputStream, options); String content = byteArrayOutputStream.toString(); // 关闭流 byteArrayOutputStream.close(); // 替换图片数据 // for (Map.Entry entry : image.entrySet()) { // content = content.replace(entry.getKey(), BASE64_IMAGE_PREFIX + entry.getValue()); // } return content; } 复制代码

此处是将".docx"格式得Word文档转换为html渲染

首先第一步转换参数设置: 在这里可以将XHTMLOptions理解为一个容器,create方法是创建了一个实例,然后setExtractor可以理解为一个图片转换器,后面几个set没去具体探究,只是理解为给这个转换器设置格式的,到时候直接按要求填充参数就好。

new XWPFDocument 是创建了一个".docx"文件的实例,参数是InputStream格式,也就是读取出来的文档流数据。

XHTMLConverter.getInstance().convert(document, byteArrayOutputStream, options)是正儿八经的转换器,getInstance获取到转换器工厂,convert获取到转换器实例,转换器的三个参数:document:拿到的word文档加载到的doc对象(前端不是也分什么doc、dom对象吗,我感觉是类似这样的,我不太懂哈);byteArrayOutputStream:读取到的内容要放到这个字节数组流里;options:按照这个设置好的格式往里面写(这是我简单粗暴的理解); 之后关闭流,直接返回byteArrayOutputStream.tosTring的字符串,自动渲染就好了。

这里面代码原作老哥做了一个修改:原先是下面被我注释掉的替换图片数据的部分,后面修改成了这行代码:

// 设置图片路径,这里替换为 base64 字符 options.URIResolver(image::get); 复制代码

先说下面for循环:前面在options.setExtracto的时候是已经设置好了对图片的处理,emmm就是在转换器转换的时候会把img标签的图片put进去了(具体什么原理我不懂哈,知道是这样的就行,有心的可以去瞅一下源码),然后entrySet或拿到所有图片信息,返回一个视图,在for里面遍历,通过replace将准备返回的字符串里面的img全部替换调,前面设置的格式是将图片直接转换成了Base64,这个格式可以在img标签里直接渲染成图片。这样就能够保证把word里面的图片也同步转换过去。

这时候小弟提了一个问题:提取出来的set有序吗,怎么保证能够原位替换,而不会错位呢?老哥回答说:概率极小,不考虑这回事。然后我去看了一下:

QQ图片20220122113808.png

QQ图片20220122113854.png 真相大白,返回的是linkset,有序,并且里面生成的KEY是按照自己的规则生成的一个唯一对应的KEY,所以不需要担心,错位,哦豁。

但是因为这个问题呢,老哥去重新修改了一下代码:就是上面的修改options.URIResolver(image::get);

········(午休结束,继续)

在这里,老哥直接设置了图片路径,(说实话,老弟儿不懂这个方法,也没去看,单纯靠自己理解噢,希望你们别被误导)Extractor已经将图片转换为Base64,通过URIResolver方法,又把Base64给img标签设置进去,这时候的操作对象应该是面对整个doc的,一一对应,所以不会存在替换失败的问题。(老哥反应好快啊)

这样呢,也解决了图片渲染的问题。

逻辑代码(转换".doc"格式Word) /** * doc(2003版本word) 转换成 html * * @param docIs doc 文件输入流 * @return 转换成的 html 代码 * @throws IOException 异常 */ public static String docToHtml(InputStream docIs) throws IOException, ParserConfigurationException, TransformerException { // 构建文档对象 HWPFDocument wordDocument = new HWPFDocument(docIs); WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); // 保存图片数据,并进行 base64 编码 wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> BASE64_IMAGE_PREFIX + Base64.getEncoder().encodeToString(content)); wordToHtmlConverter.processDocument(wordDocument); // 解析word文档 Transformer serializer = TransformerFactory.newInstance().newTransformer(); serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); serializer.setOutputProperty(OutputKeys.METHOD, "html"); // 用于读取转换后的数据 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 转换 word serializer.transform(new DOMSource(wordToHtmlConverter.getDocument()), new StreamResult(byteArrayOutputStream)); // 关闭流 byteArrayOutputStream.close(); return byteArrayOutputStream.toString(); } 复制代码

这里和上面的区别在于转换器工厂改变了。这里通过new HWPFDocument(docIs)获取到DOC对象,然后DocumentBuilderFactory.newInstance()获取转换器工厂对象,newDocumentBuilder()获取到转换器对象,最终由newDocument()返回一个Document类型,WordToHtmlConverter参数是Document类型。setPicturesManager可以理解为一个图片转换器插件,这里的几个set也是在设置格式。Transformer也是一种格式的转换器

image.png 这个转换器老弟儿就没有细看了,只知道是转换器哈。最终也是写入到byteArrayOutputStream里,然后返回字符串。

PS:补几张图

image.png

image.png

因为目前环境有点问题,还无法判断是否能够将图片渲染到富文本编辑器,但是字体样式是可以的。 (环境问题为拉取不到nacos服务里的配置信息,一直提示访问超时,但是网站可以正常访问,配置文件也是bootstrap.yml,隔壁同事帮我搞了半天,也还是不行,网络问题,目前还没解决~~~)

第一次写文,感觉还是思路没有整理清楚,一些东西也没有细究是个什么玩意儿,思维存在混乱~~~继续学习吧!

注明:代码出自群里老哥之手,链接:gitee.com/amjacks/top…

同时欢迎进入老哥群聊一起技术探讨,企鹅群:673318747



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有